#include "myhutu.h"
#include <QFontMetrics>
#include <QTimerEvent>
#include <QToolBar>
#include <QFileDialog>
#include <QMessageBox>
#include <QImage>
#include <QRectF>
#include <QInputDialog>

myhutu::myhutu(QWidget *parent)
    : QFrame(parent),
    mousePress(false), isDragging(false), isScaling(false), scaleLevel(100),
    offset(40, 100), isDrawingLine(false), isDrawingCurve(false),
    isDrawingEllips(false), isDrawingRect(false), isAddText(false),
    canUndo(false),textPosition(200, 200), textColor(Qt::black), isTextDragging(false),
    currentDraggingText(nullptr),isTextEditing(false),isTextDrawingFinished(false),
    vActions(),  history(), lastMouseEvent(nullptr),isTextBeingEdited(false)
{
    color = QColor(0, 0, 0);
    linesize = 1;
    scaleLevel = 40;
    startTimer(10); // 启动一个定时器，每个10毫秒产生一个定时器事件
    setMouseTracking(true);
    //初始化文本编辑器
    textEdit = new QTextEdit(this);  // 初始化编辑器
    textEdit->hide();  // 初始时隐藏编辑器
    textEdit->setFixedSize(100, 30);  // 设置编辑器大小
    textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);  // 隐藏滚动条
    textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    textEdit->setFrameShape(QFrame::NoFrame);  // 无边框
    textEdit->setAttribute(Qt::WA_InputMethodEnabled, true);  // 启用输入法
    textEdit->setGeometry(0, 0, 100, 30);  // 设置初始大小，可根据实际调整
    connect(textEdit, &QTextEdit::textChanged, this, [this]() {
        if (isTextBeingEdited && currentDraggingText) {  // 修改此处判断条件，添加对新标志位的判断
            QString newText = textEdit->toPlainText().trimmed();
            // 更严谨地判断文本是否为空，添加对文本长度的检查
            currentDraggingText->text = newText;
            qDebug() << "已更新文字内容为: " << currentDraggingText->text;
            update();
        }
    });
    // 去掉错误的lostFocus信号连接，保留事件过滤器相关代码
    textEdit->installEventFilter(this);
}


myhutu::~myhutu()
{
    delete textEdit;  // 释放编辑器
}

bool myhutu::isInTextEditMode()
{
    return isTextEditing;
}
bool myhutu::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == textEdit) {
        if (event->type() == QEvent::FocusOut) {
            // 当textEdit失去焦点时执行的逻辑
            textEdit->hide();
            isTextEditing = false;
            isTextDrawingFinished = true;
            isTextBeingEdited = false;  // 重置正在有效编辑文字标志位为false
            update();
            return true;  // 表示事件已被处理，不再继续传递
        }
    }
    return QFrame::eventFilter(watched, event);
}
// 重写keyPressEvent函数来处理回车键按下逻辑
void myhutu::keyPressEvent(QKeyEvent *event)
{

    QFrame::keyPressEvent(event);  // 调用基类的事件处理
}
// 鼠标按下事件处理函数
void myhutu::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)
    {
        if (!loadedImage.isNull()) {
            QRectF imageRect(offset.x(), offset.y(),
                             loadedImage.width() * scaleLevel / 100.0,
                             loadedImage.height() * scaleLevel / 100.0);
            if (imageRect.contains(event->pos())) {
                isDragging = true;
                startpos = event->pos();
                return;
            }
        }
        if (isDrawingLine) {
            mousePress = true;
            startpos = event->pos();
            currentpos = startpos;
            addAction(DRAW_LINE, QVariant::fromValue(QLine(startpos, startpos)), color, linesize);
        }
        else if (isDrawingCurve)
        {
            mousePress = true;
            startpos = event->pos();
        }
        if (isDrawingEllips || isDrawingRect)
        {
            mousePress = true;
            startpos = event->pos();
            endpos = startpos;
            if (isDrawingEllips) {
                addAction(DRAW_ELLIPS, QVariant::fromValue(QRect(startpos, startpos)), color, linesize);
            }
            else {
                addAction(DRAW_RECT, QVariant::fromValue(QRect(startpos, startpos)), color, linesize);
            }
        }
        if (isAddText) {
            lastMouseEvent = event;
            QPoint adjustedPos = event->pos();  // 获取点击位置
            adjustedPos.setX(qMax(0, qMin(adjustedPos.x(), width() - 1)));  // 限制 x 坐标
            adjustedPos.setY(qMax(0, qMin(adjustedPos.y(), height() - 1)));  // 限制 y 坐标

            // 添加新的文字对象
            TextAndPosition newText("", adjustedPos, textColor);
            vTextAndPosition.push_back(newText);
            isAddText = false;
            currentDraggingText = &vTextAndPosition.back();  // 设置当前拖动的文字

            // 显示编辑器
            textEdit->move(adjustedPos);  // 将编辑器移动到点击位置
            textEdit->clear();  // 清空编辑器内容
            textEdit->show();
            textEdit->setFocus();  // 确保编辑器获取焦点
            textEdit->setAttribute(Qt::WA_InputMethodEnabled, true);
            isTextEditing = true;  // 更新状态变量
            isTextDrawingFinished = false;
            isTextBeingEdited = true;
            qDebug() << "进入添加文字模式，编辑器显示在位置: " << adjustedPos;
            update();
        }
        else if (isTextBeingEdited) {
            // 如果正在编辑文字，且点击位置不在编辑器内，则关闭编辑器
            if (!textEdit->geometry().contains(event->pos())) {
                QString newText = textEdit->toPlainText().trimmed();  // 获取编辑器的内容
                if (!newText.isEmpty() && currentDraggingText) {
                    currentDraggingText->text = newText;  // 更新文字内容
                }
                textEdit->hide();  // 隐藏编辑器
                textEdit->clearFocus();  // 释放焦点
                isTextEditing = false;  // 更新状态变量
                isTextDrawingFinished = true;
                isTextBeingEdited = false;
                update();  // 触发重绘
                qDebug() << "鼠标点击编辑器外，文字编辑完成，编辑器已关闭";
            }
        }
        // 判断点击是否在已有文字上，启动文字拖动
        else {
            startTextDragging(event);
            if (isTextDragging && currentDraggingText) {
                isTextDragging = true;
                // 可以记录一下拖动开始的位置等信息，方便后续计算偏移量
                startpos = event->pos();
            }
        }
    }
}

// 鼠标滚轮事件处理函数
void myhutu::wheelEvent(QWheelEvent *event)
{
    if (!loadedImage.isNull()) {
        QRectF imageRect(offset.x(), offset.y(),
                         loadedImage.width() * scaleLevel / 100.0,
                         loadedImage.height() * scaleLevel / 100.0);
        if (imageRect.contains(event->position().toPoint())) {
            int delta = event->angleDelta().y();
            if (delta > 0) {
                scaleLevel++;
            }
            else if (delta < 0) {
                scaleLevel--;
            }
            if (scaleLevel < 10) scaleLevel = 10;
            QWidget::wheelEvent(event);
        }
    }
}

// 定时器事件处理函数，用于触发重绘
void myhutu::timerEvent(QTimerEvent *event)
{
    repaint();
}

// 鼠标移动事件处理函数
void myhutu::mouseMoveEvent(QMouseEvent* event)
{
    if (mousePress) {
        currentpos = event->pos();
        if (isDrawingCurve)
        {
            QLine line(startpos, currentpos);
            V.append(line);
            startpos = currentpos;
        }
    }
    else if (isDragging) {
        currentpos = event->pos();
        offset += currentpos - startpos;
        startpos = currentpos;
        update();
    }
    if (isDrawingEllips||isDrawingRect)
    {
        endpos = event->pos();
    }
    if (isTextDragging && currentDraggingText) {
        updateTextPosition(event);
    }
    else if (isTextDragging && currentDraggingText) {
        QPoint offset = event->pos() - startpos;
        currentDraggingText->position += offset;
        startpos = event->pos();
        update();
    }
}
void myhutu::resetTextStates()
{
    textEdit->hide();
    isTextEditing = false;
    isTextDrawingFinished = false;
}
// 鼠标释放事件处理函数
void myhutu::mouseReleaseEvent(QMouseEvent *event)
{
    if (mousePress && isDrawingLine)
    {
        mousePress = false;
        endpos = event->pos();
        QLine linet(startpos, endpos);
        vLineAndColor.append(LineAndColor({linet}, color, linesize, QVector<QRect>(), false, false));
        V.clear();
        update();
    }
    if (mousePress && isDrawingCurve)
    {
        mousePress = false;
        vLineAndColor.append(LineAndColor(V, color, linesize, QVector<QRect>(), false, false));
        V.clear();
        update();
    }
    if (mousePress && isDrawingEllips) {
        mousePress = false;
        endpos = event->pos();
        QRect ellipsRect(startpos, endpos);
        vLineAndColor.append(LineAndColor(QVector<QLine>(), color, linesize, {ellipsRect}, true, false));
        update();
    }
    if (mousePress && isDrawingRect) {
        mousePress = false;
        endpos = event->pos();
        QRect eRect(startpos, endpos);
        vLineAndColor.append(LineAndColor(QVector<QLine>(), color, linesize, {eRect}, false, true));
        update();
    }
    isDragging = false;
    isScaling = false;
    if (isTextDragging) {
        isTextDragging = false;
    }
    if (!isTextDragging &&!isAddText && isTextDrawingFinished) {
        resetTextStates();
    }
}

// 绘制事件处理函数，用于绘制图形、文字以及加载的图像等
void myhutu::paintEvent(QPaintEvent *event)
{
    QFrame::paintEvent(event);
    QPainter painter(this);
    if (textEdit->isVisible()) {
        textEdit->render(&painter);
    }
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(linesize);
    pen.setColor(color);
    pen.setCapStyle(Qt::RoundCap);
    painter.setPen(pen);

    // 绘制所有线段
    for (const LineAndColor &lineAndColor : vLineAndColor) {
        pen.setColor(lineAndColor.color);
        pen.setWidth(lineAndColor.widths);
        painter.setPen(pen);
        painter.drawLines(lineAndColor.vLine);

        for (const QRect &rect : lineAndColor.vRect) {
            if (lineAndColor.isEllips) {
                painter.drawEllipse(rect);
            }
            else if (lineAndColor.isRect) {
                painter.drawRect(rect);
            }
        }
    }

    // 先绘制虚线框相关逻辑（确保基于最新的文字位置和编辑状态）
    for (const auto &textInfo : vTextAndPosition) {
        QFont font("宋体", 12);
        painter.setFont(font);
        QFontMetrics metrics(font);
        QRect textRect = metrics.boundingRect(textInfo.text);  // 计算文字的实际大小
        textRect.moveTo(textInfo.position);  // 将文字矩形移动到正确的位置

        // 绘制虚线框
        if (isTextEditing && currentDraggingText == &textInfo) {
            QPen editPen(Qt::DotLine);
            painter.setPen(editPen);
            painter.drawRect(textRect);  // 绘制虚线框
        }

        // 绘制文字
        painter.setPen(textInfo.color);
        painter.drawText(textInfo.position, textInfo.text);
    }
    // 如果正在绘制线段，实时绘制当前线段
    if (mousePress && isDrawingLine) {
        QLine linet(startpos, currentpos);
        painter.drawLine(linet);
    }
    if (mousePress &&!isDrawingLine)
    {
        painter.drawLines(V);
    }
    if (mousePress && isDrawingEllips) {
        QRect ellipsRect(startpos, endpos);
        painter.drawEllipse(ellipsRect);
    }
    if (mousePress && isDrawingRect) {
        QRect eRect(startpos, endpos);
        painter.drawRect(eRect);
    }

    if (!loadedImage.isNull()) {
        QImage scaledImage = loadedImage.scaled(
            loadedImage.width() * (scaleLevel / 100),
            loadedImage.height() * (scaleLevel / 100),
            Qt::KeepAspectRatio,
            Qt::SmoothTransformation
            );
        painter.drawPixmap(offset.x(), offset.y(), QPixmap::fromImage(scaledImage));
    }

    for (const TextAndPosition &textAndPosition : vTextAndPosition) {
        painter.setPen(textAndPosition.color);
        painter.drawText(textAndPosition.position, textAndPosition.text);
    }
}
void myhutu::saveDrawingToImage(QImage& image)
{
    QPainter painter(&image);

    QPen pen;
    pen.setStyle(Qt::SolidLine);
    pen.setCapStyle(Qt::RoundCap);

    for (const LineAndColor &lineAndColor : vLineAndColor)
    {
        pen.setColor(lineAndColor.color);
        pen.setWidth(lineAndColor.widths);
        painter.setPen(pen);
        painter.drawLines(lineAndColor.vLine);
        for (const QRect &rect : lineAndColor.vRect)
        {
            if (lineAndColor.isEllips)
            {
                painter.drawEllipse(rect);
            }
            else if (lineAndColor.isRect)
            {
                painter.drawRect(rect);
            }
        }
    }

    for (const TextAndPosition &textAndPosition : vTextAndPosition)
    {
        painter.setPen(textAndPosition.color);
        painter.drawText(textAndPosition.position, textAndPosition.text);
    }

    if (!loadedImage.isNull())
    {
        QImage scaledImage = loadedImage.scaled(
            loadedImage.width() * (scaleLevel / 100),
            loadedImage.height() * (scaleLevel / 100),
            Qt::KeepAspectRatio,
            Qt::SmoothTransformation
            );
        painter.drawPixmap(offset.x(), offset.y(), QPixmap::fromImage(scaledImage));
    }
    for (const auto &textInfo : vTextAndPosition) {
        QFont font("宋体", 12);
        painter.setFont(font);
        QFontMetrics metrics(font);
        QRect textRect = metrics.boundingRect(textInfo.text);  // 计算文字的实际大小
        textRect.moveTo(textInfo.position);  // 将文字矩形移动到正确的位置

        // 绘制虚线框
        if (isTextEditing && currentDraggingText == &textInfo) {
            QPen editPen(Qt::DotLine);
            painter.setPen(editPen);
            painter.drawRect(textRect);  // 绘制虚线框
        }

        // 绘制文字
        painter.setPen(textInfo.color);
        painter.drawText(textInfo.position, textInfo.text);
    }
}
// 保存图片函数
void myhutu::SavePic()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save Image"), "", tr("PNG (*.png);;JPEG (*.jpg *.jpeg);;All Files (*)"));
    if (!fileName.isEmpty()) {
        QImage image(size(), QImage::Format_ARGB32);
        image.fill(Qt::white);
        saveDrawingToImage(image);
        image.save(fileName);
    }
}

// 另存为图片函数
void myhutu::SaveAsPic()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save Image As"), "", tr("PNG (*.png);;JPEG (*.jpg *.jpeg);;All Files (*)"));
    if (!fileName.isEmpty()) {
        SaveImage(fileName);
    }
}

// 保存图片（具体实现，接收文件名参数）函数
void myhutu::SaveImage(const QString &fileName)
{
    QImage image(size(), QImage::Format_ARGB32);
    image.fill(Qt::white);
    saveDrawingToImage(image);
    image.save(fileName);
}

// 打开图片函数
void myhutu::OpenPic()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("Image Files (*.png *.jpg *.bmp)"));
    if (!fileName.isEmpty()) {
        if (loadedImage.load(fileName)) {
            update();
        }
        else {
            QMessageBox::warning(this, tr("警告"), tr("无法打开文件"));
        }
    }
    else {
        QMessageBox::information(this, tr("信息"), tr("未选择文件"));
    }
}

// 进入添加文字模式函数
void myhutu::AddTexts()
{
    isAddText = true;
    textColor = color;
    isDrawingLine = false;
    isDrawingCurve = false;
    isDrawingEllips = false;
    isDrawingRect = false;
}


void myhutu::undo()
{
    if (!history.empty() && canUndo)
    {
        // 弹出历史记录栈顶元素（代表当前操作步骤对应的记录），先保存起来
        QVector<Action> currentStep = history.pop();

        // 判断历史记录栈是否还有元素，即是否能获取到上一步操作记录
        if (!history.empty())
        {
            // 获取上一步操作对应的记录
            QVector<Action> prevActions = history.top();

            // 临时数据结构，用于存储根据上一步操作记录解析出来的绘制相关数据
            QVector<LineAndColor> tempLineAndColor;
            QVector<TextAndPosition> tempTextAndPosition;

            // 根据上一步操作记录中的各个Action来更新临时数据结构
            for (const auto& action : prevActions)
            {
                switch (action.type)
                {
                case DRAW_LINE:
                    tempLineAndColor.append(LineAndColor({action.data.value<QLine>()}, action.color, action.width, {}));
                    break;
                case DRAW_RECT:
                    tempLineAndColor.append(LineAndColor({}, action.color, action.width, {action.data.value<QRect>()}, false, true));
                    break;
                case DRAW_ELLIPS:
                    tempLineAndColor.append(LineAndColor({}, action.color, action.width, {action.data.value<QRect>()}, true, false));
                    break;
                case ADD_TEXT:
                    tempTextAndPosition.append(TextAndPosition(action.data.toString(), action.data.value<QPoint>(), action.color));
                    break;
                default:
                    break;
                }
            }

            // 将临时数据结构中的内容赋值给实际用于绘制的对应数据结构
            vLineAndColor = std::move(tempLineAndColor);
            vTextAndPosition = std::move(tempTextAndPosition);
        }
        else
        {
            // 如果历史记录栈为空了（已经撤销到最初状态），清空绘制相关数据结构，并完整重置相关状态变量
            vLineAndColor.clear();
            vTextAndPosition.clear();
            currentDraggingText = nullptr;  // 添加这一行，重置指针
            isDrawingLine = false;
            isDrawingCurve = false;
            isDrawingEllips = false;
            isDrawingRect = false;
            isAddText = false;
            // 可以考虑在这里弹出提示框告知用户已撤销到最初状态
            QMessageBox::information(this, tr("提示"), tr("已撤销到最初状态，无法继续撤销"));
        }

        update();

        // 根据历史记录栈的状态更新是否可以继续撤销的标志
        canUndo =!history.empty();
    }
    else
    {
        // 如果无法撤销（比如历史记录为空等情况），弹出提示框告知用户无法撤销
        QMessageBox::warning(this, tr("警告"), tr("无法执行撤销操作，历史记录为空或不满足撤销条件"));
    }
}
// 添加操作记录函数，完善后的版本，确保历史记录的正确保存
void myhutu::addAction(ActionType type, const QVariant& data, QColor color, int width)
{
    // 创建一个新的Action对象并添加到vActions向量中
    vActions.push_back(Action(type, data, color, width));

    // 深拷贝当前的vActions向量，然后将其放入历史记录栈history中
    QVector<Action> copyActions = vActions;
    history.push(copyActions);

    canUndo = true;
}

// 将Action向量转换为LineAndColor向量的函数（用于绘制相关处理）
QVector<LineAndColor> convertToLineAndColor(const QVector<Action>& actions)
{
    QVector<LineAndColor> result;
    for (const auto& action : actions) {
        switch (action.type) {
        case DRAW_LINE:
            result.append(LineAndColor({}, action.color, action.width, {}));
            break;
        case DRAW_RECT:
            result.append(LineAndColor({}, action.color, action.width, {}));
            break;
        case DRAW_ELLIPS:
            result.append(LineAndColor({}, action.color, action.width, {}));
            break;
        case ADD_TEXT:
            result.append(LineAndColor({}, action.color, action.width, {}));
            break;
        default:
            break;
        }
    }
    return result;
}
bool myhutu::handleTextEditing()
{
    bool isEditing = false;
    QPoint mousePos = mapFromGlobal(QCursor::pos()); // 获取当前部件内的鼠标位置
    for (auto &textInfo : vTextAndPosition) {
        QRect textRect(textInfo.position, QSize(100, 100));  // 假设文字区域大小为100x100，可调整
        if (textRect.contains(mousePos)) {
            isEditing = true;
            // 这里可以添加更多代码来处理文字编辑相关逻辑，比如获取焦点等
            break;
        }
    }
    return isEditing;
}
void myhutu::startTextDragging(QMouseEvent *event)
{
    for (auto &textInfo : vTextAndPosition) {
        QRect textRect(textInfo.position, QSize(100, 100));
        if (textRect.contains(event->pos())) {
            isTextDragging = true;
            currentDraggingText = &textInfo;
            break;
        }
    }
}
void myhutu::updateTextPosition(QMouseEvent *event)
{
    if (isTextDragging && currentDraggingText) {
        QPoint adjustedPos = (event->pos() - offset).toPoint();
        adjustedPos.setX(qMax(0, qMin(adjustedPos.x(), width() - 1))); // 限制x坐标在画板宽度范围内
        adjustedPos.setY(qMax(0, qMin(adjustedPos.y(), height() - 1))); // 限制y坐标在画板高度范围内
        currentDraggingText->position = adjustedPos;
        update();  // 更新画板显示，让文字显示在新的位置
    }
}
